import {
	IParam,
	IUIActionResult,
	IActionModel,
	IContext,
	IAbility,
	IHttpResponse,
	deepCopy,
	IViewAbility,
	srfpluralize,
	hasFunction,
	formatUrlString,
    IRedirectInput,
    transformDoData
} from '@/core';
import { Http } from '@/http';
import { EntityUIServiceBase } from '../entity-ui-service-base';
{{#if appEntity.allPSAppDEUILogics}}
	{{#each appEntity.allPSAppDEUILogics as | uiLogic |}}
import {{pascalCase uiLogic.codeName}}UILogic from './{{spinalCase uiLogic.codeName}}-ui-logic';
	{{/each}}
{{/if}}
{{#if appEntity.allPSAppDEUIActions}}
{{importPlugin 'uiaction' appEntity}}
{{/if}}

/**
 * {{appEntity.logicName}}UI服务对象基类
 * 基于template/src/ui-service/\{{appEntities}}/\{{appEntities}}-ui-service-base.ts.hbs生成
 *
 * @export
 * @class {{pascalCase appEntity.codeName}}UIServiceBase
 * @extends {UIService}
 */
export class {{pascalCase appEntity.codeName}}UIServiceBase extends EntityUIServiceBase {

	/**
   * Creates an instance of {{pascalCase appEntity.codeName}}UIServiceBase
   * 
   * @param {*} [opts={}]
   * @memberof {{pascalCase appEntity.codeName}}UIServiceBase
   */
  constructor(opts: IParam = {}) {
    super(opts);
{{#if appEntity.keyPSAppDEField}}
    this.appDeKeyFieldName = '{{lowerCase appEntity.keyPSAppDEField.codeName}}';
{{/if}}
		// 是否启用主状态
		this.isEnableDEMainState = {{#if appEntity.enableDEMainState}}true{{else}}false{{/if}};
{{#if appEntity.mainStatePSAppDEFields}}
		// 主状态属性集合
		this.mainStateFields = [
    {{~#each appEntity.mainStatePSAppDEFields as | mainStateDEField |~}}
      	'{{lowerCase mainStateDEField.codeName}}'{{#unless @last}},{{/unless}}
    {{~/each~}}
      	];
{{/if}}
{{#if appEntity.allPSDEMainStates}}
    // 主状态集合Map
  {{#each appEntity.allPSDEMainStates as | mainState |}}
      this.allDeMainStateMap.set('{{mainState.mSTag}}', '{{mainState.mSTag}}');
  {{/each}}
      // 主状态操作标识Map
  {{#each appEntity.allPSDEMainStates as | mainState |}}
      this.allDeMainStateOPPrivsMap.set(
			'{{mainState.mSTag}}',
			Object.assign({ {{#each appEntity.allPSDEOPPrivs as | deOPPriv |}}'{{deOPPriv.name}}':{{#if deOPPriv.oPPrivAllowMode}}0{{else}}1{{/if}}{{#unless @last}},{{/unless}}{{/each}} }, { {{#each mainState.psDEMainStateOPPrivs as | deMainStateOPPriv |}}'{{deMainStateOPPriv.name}}':{{#if deMainStateOPPriv.oPPrivAllowMode}}1{{else}}0{{/if}}{{#unless @last}},{{/unless}}{{/each}} })
		);
  {{/each}}
{{/if}}
{{#each appEntity.allPSAppViews as | page |}}
	  this.allViewMap.set('{{page.funcViewMode}}:{{page.funcViewParam}}', { viewName: '{{page.codeName}}', viewType: '{{page.viewType}}', srfappde: '{{lowerCase (pluralize appEntity.codeName)}}', deCodeName: '{{page.psAppDataEntity.codeName}}' })
{{/each}}
  	}

  {{!--  遍历界面行为   --}}
{{~#each appEntity.allPSAppDEUIActions as | appDEUIAction | }}
	{{#or (eq appDEUIAction.uIActionMode 'FRONT') (eq appDEUIAction.uIActionMode 'BACKEND') (eq appDEUIAction.uILogicAttachMode 'REPLACE')}}

	/**
	 * {{appDEUIAction.caption}}
	 *
	 * @param {*} params
	 * @memberof {{pascalCase appEntity.codeName}}UIServiceBase
	 */
  public async {{appDEUIAction.codeName}}(
    uiContext: IContext,
    uiViewParams: IParam,
    uiData: IParam[],
    event: MouseEvent,
    ability: IAbility
  ): Promise<IUIActionResult> {
		{{#if appDEUIAction.psSysPFPlugin}}
			{{> @macro/plugins/ui-action/ui-action-use.hbs appPlugin=appDEUIAction.psSysPFPlugin}}
		{{else}}
			{{#eq appDEUIAction.uILogicAttachMode 'REPLACE'}}
		//	替换执行界面逻辑
		return await this.executeUILogic('{{#if appDEUIAction.psAppDEUILogic}}{{appDEUIAction.psAppDEUILogic.codeName}}{{/if}}', uiContext, uiViewParams, uiData, event, ability);
			{{else}}
				{{#eq (upperCase appDEUIAction.actionTarget) 'MULTIDATA'}}
		throw new Error('多项数据界面行为暂不支持');
				{{else}}
        const actionModel: IActionModel = {
            actionTarget: '{{upperCase appDEUIAction.actionTarget}}',
			reloadData: {{appDEUIAction.reloadData}},
			refreshMode: {{appDEUIAction.refreshMode}},
			entityCodeName: '{{appEntity.codeName}}',
			keyFieldCodeName: '{{appEntity.keyPSAppDEField.codeName}}',
            majorFieldCodeName: '{{appEntity.majorPSAppDEField.codeName}}',
					{{#eq appDEUIAction.uILogicAttachMode 'AFTER'}}
			uILogicAttachMode: '{{appDEUIAction.uILogicAttachMode}}',
			deUILogicTag: '{{#if appDEUIAction.psAppDEUILogic}}{{appDEUIAction.psAppDEUILogic.codeName}}{{/if}}',
					{{/eq}}
					{{#if appDEUIAction.nextPSUIAction}}
			nextAction: {
				name: '{{appDEUIAction.nextPSUIAction.codeName}}',
						{{#if appDEUIAction.nextPSUIAction.psAppDataEntity}}
				actionDeCodeName: '{{appDEUIAction.nextPSUIAction.psAppDataEntity.codeName}}',
						{{/if}}
						{{#if appDEUIAction.nextPSUIAction.predefinedType}}
				predefinedType: '{{appDEUIAction.nextPSUIAction.predefinedType}}',
						{{/if}}
			},
					{{/if}}
			closeEditView: {{appDEUIAction.closeEditView}},
					{{#if appDEUIAction.psNavigateContexts}}
			navContexts: {{> @macro/common/navparam.hbs appNavParams=appDEUIAction.psNavigateContexts}},
					{{/if}}
					{{#if appDEUIAction.psNavigateParams}}
			navParams: {{> @macro/common/navparam.hbs appNavParams=appDEUIAction.psNavigateParams}},
					{{/if}}
		};
					{{#if appDEUIAction.saveTargetFirst}}
		if (ability && (ability as unknown as IDECtrlAbility).save instance Function) {
			const result = await (ability as unknown as IDECtrlAbility).save(viewParams);
						{{#eq appDEUIAction.actionTarget 'SINGLEDATA'}}
			if (uiData && uiData.length > 0) {
				Object.assign(uiData[0], result.data);
			}
						{{else}}
			uiData = result.data;
						{{/eq}}
		}
					{{/if}}
		// 根据行为目标 合并行为参数
		const { context, viewParams, data } = await this.handleUIActionParam(uiContext, uiViewParams, uiData, actionModel);
				{{#eq appDEUIAction.uIActionMode 'FRONT'}}
    	{{> @macro/ui-action/front.hbs appDEUIAction=appDEUIAction}}
    			{{/eq}}
    			{{#eq appDEUIAction.uIActionMode 'BACKEND'}}
    	{{> @macro/ui-action/backend.hbs appDEUIAction=appDEUIAction appEntity=appEntity}}
    			{{/eq}}
				{{/eq}}
			{{/eq}}
    {{/if}}
  }
	{{/or}}
{{/each}}

  /**
    * 获取指定数据的重定向页面
    * 
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param redirectParam 重定向视图输入参数
	* @memberof {{pascalCase appEntity.codeName}}UIServiceBase
    */
    public async getAppRDView(
        context: IContext,
		viewParams: IParam,
		data: IParam,
		redirectParam: IRedirectInput
    ){
        // 进行数据查询
        const service = await App.getDataService("{{appEntity.codeName}}", context);
        const tempContext: IContext = deepCopy(context);
        const key: string = '{{lowerCase appEntity.codeName}}';
        let srfkey: string | null = null;
        if (data && data.hasOwnProperty(key)) {
            srfkey = data[key];
        } else if (context && context[key]) {
            srfkey = context[key];
        } else if (viewParams && viewParams[key]) {
            srfkey = viewParams[key];
        }
        Object.assign(tempContext, { [key]: srfkey });
        let result: any;
        if (redirectParam.redirectAction && service[redirectParam.redirectAction] && service[redirectParam.redirectAction] instanceof Function) {
            result = await service[redirectParam.redirectAction](tempContext, data);
        } else {
            result = await service.Get(tempContext, data);
        }
        const curData:any = result.data;
        // 判断当前数据模式,默认为true,todo
        const iRealDEModel:boolean = true;
        let bDataInWF: boolean = false;
		let bWFMode:any = false;
		if (redirectParam.isEnableWorkflow) {
            return this.getWFView();
        } else {
            if (viewParams && viewParams.srfwf && this.InWorkflowArray.indexOf(viewParams.srfwf) !== -1) {
                return this.getWFView();
            }
        }
        let strPDTViewParam: string = await this.getDESDDEViewPDTParam(curData, bDataInWF, bWFMode);
        return this.allViewMap.get(strPDTViewParam);
    }

	/**
	 * 获取实体单数据实体视图预定义参数
	 *
	 * @param curData 当前数据
	 * @param bDataInWF 是否有数据在工作流中
	 * @param bWFMode   是否工作流模式
	 * @memberof {{pascalCase appEntity.codeName}}UIServiceBase
	 */
	public async getDESDDEViewPDTParam(
		curData: any,
		bDataInWF: boolean,
		bWFMode: boolean
	) {
		let strPDTParam: string = '';
		if (bDataInWF) {
			// TODO 判断数据是否在流程中
		}
		// TODO 多表单
		const multiFormDEField: string | null = {{#if appEntity.formTypePSAppDEField}}'{{lowerCase appEntity.formTypePSAppDEField.codeName}}'{{else}}null{{/if}};

		const isApp = App.getProjectSetting().isApp;
		if (multiFormDEField) {
			const objFormValue: string = curData[multiFormDEField];
			if (isApp) {
				return 'MOBEDITVIEW:' + objFormValue;
			}
			return 'EDITVIEW:' + objFormValue;
		}
		if (isApp) {
			if (this.getDEMainStateTag(curData)) {
				return `MOBEDITVIEW:MSTAG:${this.getDEMainStateTag(curData)}`;
			}
			return 'MOBEDITVIEW:';
		}
		if (this.getDEMainStateTag(curData)) {
			return `EDITVIEW:MSTAG:${this.getDEMainStateTag(curData)}`;
		}
		return 'EDITVIEW:';
	}

{{#if appEntity.allPSAppDEUILogics}}
  /**
    * 执行界面逻辑
    * @param logicTag 界面逻辑标识
    * @param context 应用上下文 
    * @param viewParams 视图参数
    * @param data 业务数据
    * @param event 事件对象
    * @param ability 当前环境能力
	* @memberof {{pascalCase appEntity.codeName}}UIServiceBase
    */
  public async executeUILogic<T extends IAbility>(logicTag: string, context: IContext, viewParams: IParam, data: IParam[], event: MouseEvent, ability: T): Promise<IUIActionResult> {
  {{#each appEntity.allPSAppDEUILogics as | uiLogic |}}
		if (logicTag === "{{uiLogic.codeName}}") {
			return await {{pascalCase uiLogic.codeName}}UILogic.getInstance().execute(context, viewParams, data[0], event, ability);
		}
  {{/each}}
		return { ok: true, data: null };
  }
{{/if}}
}